%{     /* PARSER */

#include "parser.hh"
#include "FServer/MySQL/MySQLScanner.h"
#include <string>

#define yylex parser.scanner_->yylex
%}

%code requires
{
  #include <iostream>
  #include "FServer/MySQL/MySQLParser.h"
  #include "FServer/MySQL/MySQLStatement.h"
  #include "location.hh"
  #include "position.hh"
}

%code provides
{
  namespace keeper_server
  {
    // Forward declaration of the MySQLParser class
    class MySQLParser;
    class MySQLStatement;

    inline void
    yyerror (const char* msg)
    {
      std::cerr << msg << std::endl;
    }
  }
}



%language "C++"
%locations
%defines
%debug
%define api.namespace {keeper_server}
%define api.parser.class {Parser}
/*
%define parser_class_name {Parser}
%error-verbose
*/
%define parse.error verbose
%parse-param {MySQLParser &parser} {MySQLStatement &stmt}
%lex-param {MySQLParser &parser} {MySQLStatement &stmt}

%union
{
 /* YYLTYPE */
  char* strval;
}

%type<strval> expr ident

%token <strval> SESSIONVAR
%token <strval> NAME
%token <strval> INTNUM

/* Tokens */
%token TOK_EOF 0
%token SELECT
%token LIMIT

/* Entry point of grammar */
%start start

%%

start:
    SELECT expr LIMIT ident
    {
      stmt._tmps.push_back("SELECT");
      stmt._tmps.push_back($2);
      stmt._tmps.push_back("LIMIT");
      stmt._tmps.push_back($4);
    }
    ;

expr:
    SESSIONVAR
    {
      $$ = {$1};
    }
    ;

ident:
    NAME
    {
      $$ = {$1};
    }
    | INTNUM
    {
      $$ = {$1};
    }
    ;

%%

namespace keeper_server
{
    void Parser::error(const location&, const std::string& m)
    {
        std::cerr << *parser.location_ << ": " << m << std::endl;
        parser.error_ = (parser.error_ == 127 ? 127 : parser.error_ + 1);
    }
}
